package io.agora.openlive.ui;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Set;

import io.agora.Logger;
import io.agora.openlive.R;
import io.agora.openlive.model.AGEventHandler;
import io.agora.openlive.model.ConstantApp;
import io.agora.openlive.model.VideoStatusData;
import io.agora.rtc.Constants;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;

import static io.agora.Logger.d;

public class LiveRoomActivity extends BaseActivity implements AGEventHandler {


    private GridVideoViewContainer mGridVideoViewContainer;

    private RelativeLayout mSmallVideoViewDock;

    private boolean isCallVideo;

    private final HashMap<Integer, SoftReference<SurfaceView>> mUidsList = new HashMap<>(); // uid = 0 || uid == EngineConfig.mUid
    private ImageView ivSwitchAudio;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_live_room);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return false;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        return false;
    }

    /*是否为双向*/
    private boolean isBroadcaster(int cRole) {
        return cRole == Constants.CLIENT_ROLE_BROADCASTER;
    }

    /*是否为双向*/
    private boolean isBroadcaster() {
        return isBroadcaster(config().mClientRole);
    }


    /*初始化配置  流畅度    默认240p*/
    private void doConfigEngine(int cRole) {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        int prefIndex = pref.getInt(ConstantApp.PrefManager.PREF_PROPERTY_PROFILE_IDX, ConstantApp.DEFAULT_PROFILE_IDX);
        // 索引越界  取默认240p
        if (prefIndex > ConstantApp.VIDEO_PROFILES.length - 1) {
            prefIndex = ConstantApp.DEFAULT_PROFILE_IDX;
        }
        int vProfile = ConstantApp.VIDEO_PROFILES[prefIndex];

        worker().configEngine(cRole, vProfile);
    }

    @Override
    protected void initUIandEvent() {
        // 添加事件处理
        event().addEventHandler(this);


        Intent intent = getIntent();
        int cRole = intent.getIntExtra(ConstantApp.ACTION_KEY_CROLE, 0);

        if (cRole == 0) {
            throw new RuntimeException("Should not reach here");
        }

        // 房间名
        String roomName = intent.getStringExtra(ConstantApp.ACTION_KEY_ROOM_NAME);

        // 初始化配置
        doConfigEngine(cRole);

        // 大容器  平分整个屏幕  ReclerView
        mGridVideoViewContainer = (GridVideoViewContainer) findViewById(R.id.grid_video_view_container);
        // 大容器条目点击事件处理
        mGridVideoViewContainer.setItemEventHandler(new VideoViewEventListener() {

            // 双击
            @Override
            public void onItemDoubleClick(View v, Object item) {
                d(this, "[onItemDoubleClick] " + v + "mUid = " + ((VideoStatusData) item).mUid);

                // 只有一个  不会有用这个容器  所以不作任何处理
                if (mUidsList.size() < 2) {
                    d(this, "[onItemDoubleClick] 只有一个");
                    return;
                }
                /*// 默认类型
                if (mViewType == VIEW_TYPE_DEFAULT) {
                    // 默认类型
                    d(this, "[onItemDoubleClick] mViewType == VIEW_TYPE_DEFAULT");
                    switchToSmallVideoView(((VideoStatusData) item).mUid);

                } else {
                    // 其他类型
                    d(this, "[onItemDoubleClick] mViewType 其他类型");
                    switchToDefaultVideoView();
                }*/

            }

        });
        // 切换扬声器模式
        ImageView ivLoudspeaker = (ImageView) findViewById(R.id.iv_loudspeaker);
        // 切换语音模式
        ivSwitchAudio = (ImageView) findViewById(R.id.iv_switch_audio);
        // 切换摄像头
        ImageView ivSwitchCamera = (ImageView) findViewById(R.id.iv_switch_camera);
        // 静音
        ImageView ivMute = (ImageView) findViewById(R.id.iv_mute);

        // 是双向
        if (isBroadcaster(cRole)) {
            d(this, "[initUIandEvent]是双向的");
            // 创建一个SurfaceView显示自己
            SurfaceView surfaceV = RtcEngine.CreateRendererView(getApplicationContext());
            // 设置显示本地视频
            rtcEngine().setupLocalVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_HIDDEN, 0));
            // 显示在窗口顶层
            surfaceV.setZOrderOnTop(true);
            // 覆盖其他SurfaceView
            surfaceV.setZOrderMediaOverlay(true);
            // 添加到列表  uid和SurfaceView一一对应
            mUidsList.put(0, new SoftReference<>(surfaceV)); // get first surface view
            showSwitchAudio();
            // 初始化容器  本地
            mGridVideoViewContainer.initViewContainer(getApplicationContext(), 0, mUidsList); // first is now full view

            worker().preview(true, surfaceV, 0);
            broadcasterUI(ivLoudspeaker, ivSwitchAudio, ivSwitchCamera, ivMute);
        } else {
            // 观众模式
            audienceUI(ivLoudspeaker, ivSwitchAudio, ivSwitchCamera, ivMute);
        }

        // 加入房间
        worker().joinChannel(roomName, config().mUid);

    }

    private void showSwitchAudio() {
        ivSwitchAudio.setVisibility(mUidsList.size() > 1 ? View.VISIBLE : View.GONE);
    }

    private void broadcasterUI(ImageView ivLoudspeaker, ImageView ivSwitchAudio, ImageView ivSwitchCamera, ImageView ivMute) {
        ivLoudspeaker.setVisibility(View.GONE);

        // 摄像头模式
        ivSwitchAudio.setTag(true);
        ivSwitchAudio.setSelected(true);
        // TODO WQ 设置转换音频
        ivSwitchAudio.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Object tag = v.getTag();
                if (tag != null && (boolean) tag) {
                    //doSwitchToBroadcaster(false);
                    // 暂停本地视频
                    int result = worker().getRtcEngine().muteLocalVideoStream(true);
                    //worker().getRtcEngine().disableVideo();
                    //worker().getRtcEngine().enableLocalVideo(false);
                    v.setSelected(false);
                    v.setTag(false);
                    Logger.d(LiveRoomActivity.this, "【暂停本地视频流】 暂停了 result" + result);
                } else {
                    //doSwitchToBroadcaster(true);
                    // 开启本地视频
                    int result =  worker().getRtcEngine().muteLocalVideoStream(false);
                    //worker().getRtcEngine().enableVideo();
                    //worker().getRtcEngine().enableLocalVideo(true);
                    v.setSelected(true);
                    v.setTag(true);
                    Logger.d(LiveRoomActivity.this, "【暂停本地视频流】 重新打开了 result" + result);
                }
            }
        });


        //ivSwitchAudio.setColorFilter(getResources().getColor(R.color.agora_blue), PorterDuff.Mode.MULTIPLY);

        ivSwitchCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                worker().getRtcEngine().switchCamera();
            }
        });

        ivMute.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Object tag = v.getTag();
                boolean flag = true;
                if (tag != null && (boolean) tag) {
                    flag = false;
                }
                // 暂停音频流开关   True: 暂停发送
                worker().getRtcEngine().muteLocalAudioStream(flag);
                ImageView button = (ImageView) v;
                button.setTag(flag);

                button.setSelected(flag);
            }
        });
    }

    /*扬声器和听筒*/
    private void setSpeakerphoneOn(boolean on) {
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        if (on) {
            // 为true打开喇叭扩音器；为false关闭喇叭扩音器.
            audioManager.setSpeakerphoneOn(true);
            // 2016年06月18日 添加的代码，恢复系统声音设置
            audioManager.setMode(AudioManager.STREAM_SYSTEM);
            setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
        } else {
            audioManager.setSpeakerphoneOn(false);//关闭扬声器
            audioManager.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL);
            setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
            //把声音设定成Earpiece（听筒）出来，设定为正在通话中
//            audioManager.setMode(AudioManager.MODE_IN_CALL);
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
        }
    }

    private void audienceUI(ImageView ivLoudspeaker, ImageView ivSwitchAudio, ImageView ivSwitchCamera, ImageView ivMute) {

        ivLoudspeaker.setVisibility(View.VISIBLE);
        ivLoudspeaker.setTag(true);
        ivLoudspeaker.setSelected(true);
        ivLoudspeaker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Object tag = v.getTag();
                if (tag != null && (boolean) tag) {
                    setSpeakerphoneOn(false);
                    v.setSelected(false);
                    Logger.d(LiveRoomActivity.this, "【扬声器】 关闭");
                } else {
                    setSpeakerphoneOn(true);
                    v.setSelected(true);
                    Logger.d(LiveRoomActivity.this, "【扬声器】 打开");
                }
            }
        });

//        ivSwitchAudio.setTag(null);
//        ivSwitchAudio.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                Object tag = v.getTag();
//                if (tag != null && (boolean) tag) {
//                    doSwitchToBroadcaster(false);
//                } else {
//                    doSwitchToBroadcaster(true);
//                }
//            }
//        });
//        ivSwitchAudio.clearColorFilter();
//        ivSwitchAudio.setVisibility(View.GONE);

        ivSwitchCamera.setVisibility(View.GONE);
//        ivMute.setTag(null);
//        ivMute.setVisibility(View.GONE);
//        ivMute.clearColorFilter();

        ivMute.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Object tag = v.getTag();
                boolean flag = true;
                if (tag != null && (boolean) tag) {
                    flag = false;
                }
                // 暂停音频流开关   True: 暂停发送
                worker().getRtcEngine().muteLocalAudioStream(flag);
                ImageView button = (ImageView) v;
                button.setTag(flag);
                button.setSelected(flag);
            }
        });

        ivMute.setTag(null);
        ivMute.setVisibility(View.VISIBLE);
    }


    @Override
    protected void deInitUIandEvent() {
        doLeaveChannel();
        event().removeEventHandler(this);

        mUidsList.clear();
    }

    private void doLeaveChannel() {
        worker().leaveChannel(config().mChannel);
        if (isBroadcaster()) {
            worker().preview(false, null, 0);
        }
    }

    public void onClickClose(View view) {
        finish();
    }

    public void onShowHideClicked(View view) {
        boolean toHide = true;
        if (view.getTag() != null && (boolean) view.getTag()) {
            toHide = false;
        }
        view.setTag(toHide);
        view.setSelected(toHide);
        doShowButtons(toHide);
    }

    /*打开悬浮窗*/
    public void openSmallVideo(View v) {

    }

    /*打开聊天*/
    public void openMessage(View v) {

    }

    private void doShowButtons(boolean hide) {

        View button1 = findViewById(R.id.iv_switch_audio);
        button1.setVisibility(hide ? View.INVISIBLE : View.VISIBLE);

        View button2 = findViewById(R.id.iv_switch_camera);
        View button3 = findViewById(R.id.iv_mute);
        if (isBroadcaster()) {
            button2.setVisibility(hide ? View.INVISIBLE : View.VISIBLE);
            button3.setVisibility(hide ? View.INVISIBLE : View.VISIBLE);
        } else {
            button2.setVisibility(View.INVISIBLE);
            button3.setVisibility(View.INVISIBLE);
        }
    }

    /*远端视频第一帧解码成功   只会调用一次  就算重新进入  或者其他情况  也不会再此调用*/
    @Override
    public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {
        doRenderRemoteUi(uid);
    }

    /*切换通信模式、true打开视频*/
    private void doSwitchToBroadcaster(boolean broadcaster) {
        final int currentHostCount = mUidsList.size();
        final int uid = config().mUid;

        // 打开视频
        if (broadcaster) {
            doConfigEngine(Constants.CLIENT_ROLE_BROADCASTER);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    doRenderRemoteUi(uid);

                    // 切换扬声器模式
                    //ImageView ivLoudspeaker = (ImageView) findViewById(R.id.iv_loudspeaker);
                    // 切换语音模式
                    //ImageView ivSwitchAudio = (ImageView) findViewById(R.id.iv_switch_audio);
                    // 切换摄像头
                    //ImageView ivSwitchCamera = (ImageView) findViewById(R.id.iv_switch_camera);
                    // 静音
                    //ImageView ivMute = (ImageView) findViewById(R.id.iv_mute);

                    //broadcasterUI(ivLoudspeaker, ivSwitchAudio, ivSwitchCamera, ivMute);

                    //doShowButtons(false);
                }
            }, 1000); // wait for reconfig engine

            /*发送本地视频流*/
            rtcEngine().muteLocalVideoStream(false);
            /*发送本地音频流*/
            // rtcEngine().muteLocalAudioStream(false);

        } else {
            // 停止本地视频流

            stopInteraction(currentHostCount, uid);
        }
    }

    /*停止本地视频流   变为观众*/
    private void stopInteraction(final int currentHostCount, final int uid) {
        doConfigEngine(Constants.CLIENT_ROLE_AUDIENCE);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                doRemoveRemoteUi(uid);

                //ImageView button1 = (ImageView) findViewById(R.id.iv_switch_audio);
                //ImageView button2 = (ImageView) findViewById(R.id.iv_switch_camera);
                //ImageView button3 = (ImageView) findViewById(R.id.iv_mute);
                //audienceUI(button1, button2, button3);

                //doShowButtons(false);
            }
        }, 1000); // wait for reconfig engine

        // 暂停发送音频
        //rtcEngine().muteLocalAudioStream(true);
        rtcEngine().muteLocalVideoStream(true);
    }

    // 初始化远端视频
    private void doRenderRemoteUi(final int uid) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                // 为远端用户创建surfaveView
                SurfaceView surfaceV = RtcEngine.CreateRendererView(getApplicationContext());
                surfaceV.setZOrderOnTop(true);
                surfaceV.setZOrderMediaOverlay(true);
                // 添加到列表
                mUidsList.put(uid, new SoftReference<>(surfaceV));

                showSwitchAudio();
                // TODO WQ设置视频显示信息
                if (config().mUid == uid) {
                    // 如果是自己
                    rtcEngine().setupLocalVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_HIDDEN, uid));
                } else {
                    // 如果是远端
                    rtcEngine().setupRemoteVideo(new VideoCanvas(surfaceV, VideoCanvas.RENDER_MODE_HIDDEN, uid));
                }


                // 如果类型为默认的 格子容器
                if (mViewType == VIEW_TYPE_DEFAULT) {
                    switchToDefaultVideoView();
                } else {
                    int bigBgUid = uid;
                    if (mSmallVideoViewAdapter != null) {
                        bigBgUid = mSmallVideoViewAdapter.getExceptedUid();
                    }
                    switchToSmallVideoView(bigBgUid);
                }
            }
        });
    }

    /*房间加入成功*/
    @Override
    public void onJoinChannelSuccess(final String channel, final int uid, final int elapsed) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                // 如果列表包含这个用户  直接返回
                if (mUidsList.containsKey(uid)) {
                    return;
                }
                // 非观众模式
                final boolean isBroadcaster = isBroadcaster();

                // 配置本人信息
                worker().getEngineConfig().mUid = uid;

                // 健壮性判断  第二次加入成功
                SoftReference<SurfaceView> surfaceV = mUidsList.remove(0);

                showSwitchAudio();

                if (surfaceV != null) {
                    // 移除再添加
                    mUidsList.put(uid, surfaceV);

                    showSwitchAudio();
                }

                // 如果非观众模式
                if (isBroadcaster) {
                    // 打开发送音频流
                    rtcEngine().muteLocalAudioStream(false);
                } else {
                    // 观众模式静音
                    // 暂停发送音频
                    rtcEngine().muteLocalAudioStream(false);
                }

                //TODO WQ 扬声器开关   确保已成功调用joinChannel。
                worker().getRtcEngine().setEnableSpeakerphone(true);
            }
        });
    }

    @Override
    public void onUserOffline(int uid, int reason) {
        Logger.d(this, "onUserOffline " + (uid & 0xFFFFFFFFL) + " " + reason);
        doRemoveRemoteUi(uid);
    }

    private void requestRemoteStreamType(final int currentHostCount) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                HashMap.Entry<Integer, SoftReference<SurfaceView>> highest = null;
                for (HashMap.Entry<Integer, SoftReference<SurfaceView>> pair : mUidsList.entrySet()) {
                    if (pair.getKey() != config().mUid && (highest == null || highest.getValue().get().getHeight() < pair.getValue().get().getHeight())) {
                        if (highest != null) {
                            rtcEngine().setRemoteVideoStreamType(highest.getKey(), Constants.VIDEO_STREAM_LOW);
                        }
                        highest = pair;
                    } else if (pair.getKey() != config().mUid && (highest != null && highest.getValue().get().getHeight() >= pair.getValue().get().getHeight())) {
                        rtcEngine().setRemoteVideoStreamType(pair.getKey(), Constants.VIDEO_STREAM_LOW);
                    }
                }
                if (highest != null && highest.getKey() != 0) {
                    rtcEngine().setRemoteVideoStreamType(highest.getKey(), Constants.VIDEO_STREAM_HIGH);
                }
            }
        }, 500);
    }

    /*移除远端UI*/
    private void doRemoveRemoteUi(final int uid) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isFinishing()) {
                    return;
                }

                // 移除UI
                mUidsList.remove(uid);

                showSwitchAudio();

                int bigBgUid = -1;
                if (mSmallVideoViewAdapter != null) {
                    bigBgUid = mSmallVideoViewAdapter.getExceptedUid();
                }


                if (mViewType == VIEW_TYPE_DEFAULT || uid == bigBgUid) {
                    //switchToDefaultVideoView();
                    /*我添加的*/
                    // mUidsList 只有视频功能的才会被添加
                    if (mUidsList.isEmpty()) {
                        Logger.d(this, "[doRemoveRemoteUi]  mUidsList = null");
                        return;
                    }
                    // 遍历判断  优先选择远端视频作为大视图
                    Set<Integer> integers = mUidsList.keySet();
                    for (Integer uid : integers) {

                        if (mUidsList.size() > 1 && uid != config().mUid) {
                            switchToSmallVideoView(uid);
                            break;
                        } else {
                            switchToSmallVideoView(uid);
                            break;
                        }
                    }

                } else {
                    switchToSmallVideoView(bigBgUid);
                }
            }
        });
    }

    private SmallVideoViewAdapter mSmallVideoViewAdapter;

    private void switchToDefaultVideoView() {
        if (mSmallVideoViewDock != null)
            mSmallVideoViewDock.setVisibility(View.GONE);
        mGridVideoViewContainer.initViewContainer(getApplicationContext(), config().mUid, mUidsList);

        mViewType = VIEW_TYPE_DEFAULT;

        int sizeLimit = mUidsList.size();
        if (sizeLimit > ConstantApp.MAX_PEER_COUNT + 1) {
            sizeLimit = ConstantApp.MAX_PEER_COUNT + 1;
        }
        for (int i = 0; i < sizeLimit; i++) {
            int uid = mGridVideoViewContainer.getItem(i).mUid;
            if (config().mUid != uid) {
                rtcEngine().setRemoteVideoStreamType(uid, Constants.VIDEO_STREAM_HIGH);
            }
        }
    }

    /*切换此id为全屏显示*/
    private void switchToSmallVideoView(int uid) {
        HashMap<Integer, SoftReference<SurfaceView>> slice = new HashMap<>(1);
        // 添加一个  uid  以及对应的surfaceView
        slice.put(uid, mUidsList.get(uid));
        // 更新这个布局   其实就是把他变成大的   而且容器里面只有这一个
        mGridVideoViewContainer.initViewContainer(getApplicationContext(), uid, slice);

        // 绑定小视图
        bindToSmallVideoView(uid);

        // 切换小的类型
        mViewType = VIEW_TYPE_SMALL;

        requestRemoteStreamType(mUidsList.size());
    }

    public int mViewType = VIEW_TYPE_SMALL;

    public static final int VIEW_TYPE_DEFAULT = 0;

    public static final int VIEW_TYPE_SMALL = 1;

    /*全屏的视图  和  小容器里面的用户列表  依赖关系*/
    private void bindToSmallVideoView(int exceptUid) {
        // TODO WQ优化学习
        if (mSmallVideoViewDock == null) {
            ViewStub stub = (ViewStub) findViewById(R.id.small_video_view_dock);
            mSmallVideoViewDock = (RelativeLayout) stub.inflate();

        }

        // 小视频容器
        RecyclerView recycler = (RecyclerView) findViewById(R.id.small_video_view_container);

        boolean create = false;

        // 如果为空
        if (mSmallVideoViewAdapter == null) {
            create = true;
            mSmallVideoViewAdapter = new SmallVideoViewAdapter(this, exceptUid, mUidsList, new VideoViewEventListener() {
                @Override
                public void onItemDoubleClick(View v, Object item) {
                    // 小视频双击事件
                    switchToSmallVideoView(((VideoStatusData) item).mUid);
                }
            });
            // 局部刷新视图  和 getItemId 返回hash配合使用
            mSmallVideoViewAdapter.setHasStableIds(true);
        }
        recycler.setHasFixedSize(true);

        recycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recycler.setAdapter(mSmallVideoViewAdapter);

        // 可以抓图
        recycler.setDrawingCacheEnabled(true);
        recycler.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_AUTO);

        if (!create) {
            mSmallVideoViewAdapter.notifyUiChanged(mUidsList, exceptUid, null, null);
        }
        recycler.setVisibility(View.VISIBLE);
        mSmallVideoViewDock.setVisibility(View.VISIBLE);
    }
}
